import type { Directive, DirectiveBinding } from 'vue'

interface AutoTitleOptions {
  always?: boolean // 是否总是显示title
  content?: string // 自定义title内容
  lines?: number // 最大行数（支持多行省略）
  addClass?: boolean // 是否自动添加__text类名，默认为true
}

const autoTitle: Directive<HTMLElement, boolean | AutoTitleOptions | string> = {
  mounted(el, binding) {
    processElement(el, binding, true)
  },
  updated(el, binding) {
    processElement(el, binding, false)
  },
  unmounted(el) {
    const observer = (el as any)._autoTitleObserver
    if (observer) {
      observer.disconnect()
      delete (el as any)._autoTitleObserver
    }
  },
}

function processElement(
  el: HTMLElement,
  binding: DirectiveBinding,
  isMounted: boolean,
) {
  const options = parseBinding(binding)

  // 自动添加__text类名（默认添加，可通过addClass: false禁用）
  if (options.addClass !== false) {
    el.classList.add(
      `__text-ellipsis${Number(options.lines) > 1 ? `-${options.lines}` : ''}`,
    )
  } else {
    el.classList.remove(
      `__text-ellipsis${Number(options.lines) > 1 ? `-${options.lines}` : ''}`,
    )
  }

  // 初始化或更新观察者
  if (isMounted) {
    observeElement(el, options)
  } else {
    updateTitle(el, options)
  }
}

function observeElement(el: HTMLElement, options: AutoTitleOptions) {
  // 先移除旧的观察者
  const oldObserver = (el as any)._autoTitleObserver
  if (oldObserver) {
    oldObserver.disconnect()
  }

  const observer = new ResizeObserver(() => {
    updateTitle(el, options)
  })

  observer.observe(el)
  ;(el as any)._autoTitleObserver = observer

  // 初始更新
  updateTitle(el, options)
}

function updateTitle(el: HTMLElement, options: AutoTitleOptions) {
  const isOverflow = options.lines
    ? checkMultilineOverflow(el, options.lines)
    : checkSinglelineOverflow(el)

  if (options.always || isOverflow) {
    el.setAttribute('title', options.content || el.textContent?.trim() || '')
  } else {
    el.removeAttribute('title')
  }
}

function checkSinglelineOverflow(el: HTMLElement): boolean {
  return el.scrollWidth > el.clientWidth
}

function checkMultilineOverflow(el: HTMLElement, lines: number): boolean {
  const lineHeight = parseFloat(getComputedStyle(el).lineHeight)
  const maxHeight = lineHeight * lines
  return el.scrollHeight > maxHeight + 1 // 加1是为了避免舍入误差
}

function parseBinding(binding: DirectiveBinding): AutoTitleOptions {
  if (typeof binding.value === 'boolean') {
    return { always: binding.value }
  }
  if (typeof binding.value === 'string') {
    return { content: binding.value }
  }
  if (typeof binding.value === 'object') {
    return binding.value
  }
  return { always: false }
}

export default autoTitle
// v-title="{ lines: 3, content: '自定义标题内容' }"
// /* 单行省略 */
// .truncate {
//   white-space: nowrap;
//   overflow: hidden;
//   text-overflow: ellipsis;
// }
//
// /* 多行省略 */
// .line-clamp-1 { -webkit-line-clamp: 1; }
// .line-clamp-2 { -webkit-line-clamp: 2; }
// .line-clamp-3 { -webkit-line-clamp: 3; }
// .line-clamp-4 { -webkit-line-clamp: 4; }
// .line-clamp-5 { -webkit-line-clamp: 5; }
//
// .line-clamp {
//   display: -webkit-box;
//   -webkit-box-orient: vertical;
//   overflow: hidden;
// }
